﻿using System;
using System.Reflection;
using Useful.GUI;

namespace Useful.MVP2
{
    public abstract class BasePresenter<M, IV, R>
        where M : class, new()
        where IV : IView
    {
        public M Model { get; private set; }
        protected IV View { get; private set; }

        public IPresenterImpl PresenterImpl { get; set; }

        public R Repository { get; set; }

        protected BasePresenter(IV view, R repository, IPresenterImpl presenterImpl)
        {
            this.PresenterImpl = presenterImpl;

            Model = new M();
            Repository = repository;
            View = view;

            View.ExceptionRaised += View_ExceptionRaised;
            View.ViewLoaded += View_Loaded;
            View.ViewClosed += View_Closed;
        }

        protected void HandleException(string msg, Exception ex)
        {
            PresenterImpl.HandleException(msg, ex);
        }

        private void View_ExceptionRaised(object sender, ExceptionEventArgs e)
        {
            PresenterImpl.HandleException(e.Message, e.Error);
        }

        private void View_Loaded(object sender, EventArgs e)
        {
            try
            {
                OnViewLoad();
            }
            catch(Exception ex)
            {
                HandleException(MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        private void View_Closed(object sender, EventArgs e)
        {
            try
            {
                OnViewClose();
            }
            catch (Exception ex)
            {
                HandleException(MethodBase.GetCurrentMethod().Name, ex);
            }
        }

        protected abstract void OnViewLoad();
        protected abstract void OnViewClose();

        protected void ShowWarring(string str)
        {
            PresenterImpl.ShowWarring(str);
        }

        protected bool ShowQuestion(string str)
        {
            return PresenterImpl.ShowQuestion(str);
        }

        protected void ShowAcessDenied(string str)
        {
            PresenterImpl.ShowAcessDenied(str);
        }

        protected void ShowWaiting(object context, string message, GuiHelper.ProcessActionDelegate progress)
        {
            PresenterImpl.ShowWaiting(context, message, progress);
        }
    }
}
